package com.itheima.em.server.service.impl.tianditu;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.CoordinateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.itheima.em.config.EagleConfig;
import com.itheima.em.config.TMapServerConfig;
import com.itheima.em.enums.CoordinateType;
import com.itheima.em.enums.ProviderType;
import com.itheima.em.exception.EagleMapException;
import com.itheima.em.service.EagleOrdered;
import com.itheima.em.service.GeoCodeService;
import com.itheima.em.util.CoordinateConverter;
import com.itheima.em.vo.CoordinateVo;
import com.itheima.em.vo.GeoResultVO;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 地理/逆地理编码 - 天地图的实现类
 *
 * (地理编码使用的是：CGCS2000 转 WGS84)
 *
 * @author MJJ
 * @version 1.0
 * @date 2023/11/26
 */
@Service("TMapGeoCodingService")
@ConditionalOnBean(TMapServerConfig.class)
public class TMapGeoCodeServiceImpl implements GeoCodeService {

    @Resource
    private TMapWebApiService tMapWebApiService;
    @Resource
    private EagleConfig eagleConfig;

    @Override
    public GeoResultVO geoCode(String address, Map<String, Object> param) {
        String url = this.eagleConfig.getTmapWebApi() + "/geocoder";

        //封装请求参数
        Map<String, Object> requestParam = new HashMap<>();
        if (CollUtil.isNotEmpty(param)) {
            for (Map.Entry<String, Object> entry : param.entrySet()) {
                requestParam.put(entry.getKey(), entry.getValue());
            }
        }
        requestParam.put("ds", "{\"keyWord\":\""+address+"\"}");
        return this.tMapWebApiService.doGet(url, requestParam, response -> {
            String body = response.body();
            JSONObject json = JSONUtil.parseObj(body);
            if (json.getInt("code") != null || json.getInt("status") != 0) {
                throw new EagleMapException(body);
            }
            GeoResultVO geoResultVO = new GeoResultVO();
            JSONObject location = json.getByPath("location", JSONObject.class);
            geoResultVO.setAddress(address);
            double [] wgs84 = CoordinateConverter.convertCGCS2000ToWGS84(location.getDouble("lon"), location.getDouble("lat"));
            geoResultVO.setLocation(new CoordinateVo(wgs84[0],wgs84[1]));
            geoResultVO.setData(json.toString());
            return geoResultVO;
        });
    }

    @Override
    public GeoResultVO geoDecode(Double longitude, Double latitude, Map<String, Object> param) {
        String url = this.eagleConfig.getTmapWebApi() + "/geocoder";

        //封装请求参数
        Map<String, Object> requestParam = new HashMap<>();
        if (CollUtil.isNotEmpty(param)) {
            for (Map.Entry<String, Object> entry : param.entrySet()) {
                requestParam.put(entry.getKey(), entry.getValue());
            }
        }
        double [] cgcs2000 = CoordinateConverter.convertWGS84ToCGCS2000(longitude, latitude);
        requestParam.put("postStr", "{\"lon\":\""+cgcs2000[0]+"\",\"lat\":\""+cgcs2000[1]+"\",\"ver\":1}");
        requestParam.put("type", "geocode");

        return this.tMapWebApiService.doGet(url, requestParam, response -> {
            String body = response.body();
            JSONObject json = JSONUtil.parseObj(body);
            if (json.getInt("code") != null || json.getInt("status") != 0) {
                throw new EagleMapException(body);
            }
            GeoResultVO geoResultVO = new GeoResultVO();
            JSONObject location = json.getByPath("result.location", JSONObject.class);
            geoResultVO.setLocation(new CoordinateVo(location.getDouble("lon"), location.getDouble("lat")));
            geoResultVO.setData(json.getJSONObject("result").toString());
            geoResultVO.setAddress(json.getByPath("result.formatted_address", String.class));
            JSONObject addressComponent = json.getByPath("result.addressComponent", JSONObject.class);
            geoResultVO.setLocationAddress(addressComponent.getStr("address"));//地点位置信息
            geoResultVO.setCountry(addressComponent.getStr("nation"));//国家
            geoResultVO.setProvince(addressComponent.getStr("province"));//省
            geoResultVO.setCity(addressComponent.getStr("city"));//市
            geoResultVO.setDistrict(addressComponent.getStr("county"));//区

            return geoResultVO;
        });
    }

    @Override
    public ProviderType getProvider() {
        return ProviderType.TMAP;
    }

    @Override
    public int getOrder() {
        return EagleOrdered.ONE;
    }
}
